package com.zanbo.clock.service.impl;

import com.zanbo.clock.domain.entity.Clock;
import com.zanbo.clock.domain.entity.Staff;
import com.zanbo.clock.domain.mapper.ClockMapper;
import com.zanbo.clock.domain.mapper.StaffMapper;
import com.zanbo.clock.exception.ServiceException;
import com.zanbo.clock.model.code.ErrorCode;
import com.zanbo.clock.service.StaffService;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author: zanbo
 * @description: 按员工数量导出签到表
 * @date: 上午 11:03 2021-4-26
 */
@Service
//@SuppressWarnings({"all"})
public class StaffServiceImpl implements StaffService {
    
    @Autowired
    private StaffMapper staffMapper;
    
    @Autowired
    private ClockMapper clockMapper;
    
    /**
     * 对签到数据遍历时的索引
     */
    private static int clockListNum = 0;
    
    /**
     * @return org.apache.poi.xssf.usermodel.XSSFWorkbook
     * @author: zanbo
     * @description: 对数据库中员工的打卡时间进行判断整合导出excel
     * @date: 上午 10:57 2021-4-26
     * @params [time]
     */
    public XSSFWorkbook outExecl(LocalDateTime time) {
        List<Staff> staff = staffMapper.selectAll();
        Example example = new Example(Clock.class);
        Example.Criteria criteria = example.createCriteria();
        example.setOrderByClause("cdate asc");
        if (staff == null) {
            //如果库中没有员工抛出异常
            throw new ServiceException(ErrorCode.EEEEERROR);
        }
        int dayOfMonth = time.with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet();
        //定义最大数防止触发其扩容机制
        List<String> table = new ArrayList<>(31);
        int lastRowNum = sheet.getLastRowNum();
        Row dataRow = sheet.createRow(lastRowNum);
        //遍历写入表格头
        for (int i = 1, j = 1; j <= dayOfMonth; i += 2, j++) {
            dataRow.createCell(i).setCellValue(j + "号签到");
            dataRow.createCell(i + 1).setCellValue(j + "号签退");
        }
        for (Staff s : staff) {
            clockListNum = 0;
            criteria.andEqualTo("uid", s.getUid());
            criteria.andGreaterThanOrEqualTo("cdate", time.with(TemporalAdjusters.firstDayOfMonth()).withHour(0).withMinute(0).withSecond(0));
            criteria.andLessThanOrEqualTo("cdate", time.with(TemporalAdjusters.lastDayOfMonth()).withHour(23).withMinute(59).withSecond(59));
            List<Clock> clockList = clockMapper.selectByExample(example);
            int size = clockList.size();
            lastRowNum = sheet.getLastRowNum();
            dataRow = sheet.createRow(lastRowNum + 1);
            dataRow.createCell(0).setCellValue(s.getUid() + s.getUname());
            //每一个员工的签到状态
            for (int i = 1, j = 1; j <= dayOfMonth; i += 2, j++) {
                dataRow.createCell(i).setCellValue(isClock(j, clockList, size));
                dataRow.createCell(i + 1).setCellValue(isClock(j, clockList, size));
            }
        }
        return workbook;
    }
    
    /**
     * @author zanbo
     * @description 根据数据库中的时间返回成当前表格的打卡状态
     * @date 上午 11:53 2021-4-26
     * @params [uid]
     * @return com.zanbo.clock.domain.entity.Staff
     */
    @Override
    public Staff findUserByUid(Long uid) {
        Staff select = staffMapper.selectOne(new Staff(null, uid, null, null));
        return select;
    }
    
    public List<Staff> findAll() {
        List<Staff> staff = staffMapper.selectAll();
        return staff;
    }
    
    public String isClock(int date, List<Clock> clockList, int size) {
        if (clockListNum >= size) {
            return "缺勤";
        }
        LocalDateTime cdate = clockList.get(clockListNum).getCdate();
        boolean AM_after = cdate.isAfter(LocalDateTime.of(cdate.getYear(), cdate.getMonth(), date, 0, 0, 0));
        boolean AM_before = cdate.isBefore(LocalDateTime.of(cdate.getYear(), cdate.getMonth(), date, 8, 0, 0));
        boolean AM_before2 = cdate.isBefore(LocalDateTime.of(cdate.getYear(), cdate.getMonth(), date, 12, 0, 0));
        if (AM_after && AM_before) {
            clockListNum++;
            return "√";
        }
        if (AM_after && AM_before2) {
            clockListNum++;
            return "迟到";
        }
        boolean PM_after = cdate.isAfter(LocalDateTime.of(cdate.getYear(), cdate.getMonth(), date, 12, 0, 1));
        boolean PM_before = cdate.isBefore(LocalDateTime.of(cdate.getYear(), cdate.getMonth(), date, 20, 0, 0));
        boolean PM_before2 = cdate.isBefore(LocalDateTime.of(cdate.getYear(), cdate.getMonth(), date, 23, 59, 59));
        if (PM_after && PM_before) {
            clockListNum++;
            return "早退";
        }
        if (PM_after && PM_before2) {
            clockListNum++;
            return "√";
        }
        return "缺勤";
    }
    
}
